home *** CD-ROM | disk | FTP | other *** search
/ Aminet 6 / Aminet 6 - June 1995.iso / Aminet / dev / debug / apurify_v1_1.lha / apurify / doc / APurify.doc < prev    next >
Encoding:
Text File  |  1995-04-10  |  14.5 KB  |  308 lines

  1.                    APurify
  2.                    -------
  3.  
  4.                (c) by Samuel DEVULDER
  5.                   April 1995
  6.  
  7.                Samuel.Devulder@info.unicaen.fr
  8.  
  9. DESCRIPTION (SHORT):
  10. --------------------
  11.     APurify is a program that allows you to detect bad accesses  to  memory
  12.     of your programs without any kind of specific external  devices  (MMU).
  13.     It avoids bugs due to accessing memory not owned by your program.
  14.  
  15. SYNOPSIS:
  16. --------
  17.     APurify [-revinfo] <Source file> [<Destination file>]
  18.  
  19.     APurify -revinfo
  20.     To get informations about APurify (name, size and date  of  modules
  21.     and number of compilation done for that version).
  22.  
  23.     APurify <Source file> <Destination file>
  24.     Analyse the assembly language source file and generate a  new  file
  25.     ready to be compiled and linked with APur.lib.    Illegal  access  to
  26.     memory of that file will be detected by APurify.  Destination  file
  27.     can be the same as source file.
  28.  
  29.     APurify <Fichier source>
  30.     Same as: APurify  <Source  file>  <Source  file>.  eg:    Destination
  31.     filename is the same as the source filename.
  32.  
  33. DESCRIPTION (A BIT LONGER):
  34. --------------------------
  35.     As a general rule, at the microprocessor level, there is  two  kind
  36.     of ways to access memory. There is direct access and indirect access to
  37.     memory. For example, in C, direct access can be viewed as accessing  to
  38.     global variables. Indirect access corresponds  to  accessing  an  array
  39.     value. More precisely, direct access corresponds to reading or  writing
  40.     a variable whose address is known at compilation  time  (or  since  the
  41.     loading of the program into the memory). Indirect access  is  used    for
  42.     variables whose adress is dynamicaly determined  by  the  program.    For
  43.     example, if p is a pointer to an array allocated by malloc(), *p is  an
  44.     indirect access. Such an access occur also in case of instruction  like
  45.     T[i] where T is a global array, because the  address  of  T[i]  is    not
  46.     known at compilation time, since it depends on the index value i. Using
  47.     indirect access to memory is called indirection.
  48.  
  49.     A regular program must not access memory not owned by it. That kind
  50.     of access can be qualified as illegal.
  51.  
  52.     Illegal direct    access    to  memory  is    not  possible,    because  by
  53.     definition, only global variables can be accessed that  way  and  those
  54.     variables belongs obviously to the program (except for code written  in
  55.     assembly language that references absolute values,    for  example:  btst
  56.     #6,$bfe001; but that kind of code can't be produced in C directly).  So
  57.     direct access to memory is always right.
  58.  
  59.     On the other hand, it is sure that indirect access  to    memory    can
  60.     be illegal. Many bugs are made by  overstepping  array  boundaries.  If
  61.     that oversteppings are in reading a value, there is not  much  trouble;
  62.     but if it is in writing, big mess can happen.
  63.  
  64.     APurify works on that kind of access by verifying the  validity  of
  65.     indirect access to memory. It remebers the memory that was allocated by
  66.     the program and check the integrity of each access. One can think  that
  67.     makes a lot of tests ! Well, yes, but APurify is  not  designed  to  be
  68.     used in the general use of programs; just  in  test  phases.  Moreover,
  69.     indirections  do  no  occur  very  often  actually.  Only  array-linked
  70.     variables produces indirections.  Thus,  the  variables  on  the  stack
  71.     ---although being accessed by indirection--- are  not  checked  because
  72.     their access is always safe (at least if there is no stack overflow !).
  73.     Also, in SMALL_DATA model, global  variables  access  is  done  through
  74.     indirection, but they are not checked.
  75.  
  76.     If an illegal access is found, APurify displays an error message on
  77.     the error stream of the program (have a look at the full  justification
  78.     of the output :^). There is two kind  of  illegal  accesses.  Some    are
  79.     accesses to memory that doesn't belong to the program (it is called  an
  80.     access between blocks), some others are accesses to a  part  of  memory
  81.     owned by a program and an  other  part  not  owned    by  it    (it  is  an
  82.     overstepping of a block).
  83.  
  84.     The memory is represented by  a  block.  Each  block  is  displayed
  85.     according to the following pattern:
  86.  
  87.                [0x<n1>(<n2>) <attr> (<text>)]
  88.  
  89.     where <n1> is the hexadecimal address of the beginning  of    the  block,
  90.     <n2> its length, <attr> 3 status characters RWS
  91.  
  92.     where R means: read-enable block
  93.           W means: write-enable block
  94.           S means: system block (block not controlled by the program).
  95.  
  96.     If one access is forbidden, the letter '-' replaces  the  corresponding
  97.     character. <text> is actually  the    name  of  the  procedure  that    has
  98.     allocated the block. If it ends with "*" that block was allocated by  a
  99.     call within the one indicated to a procedure not parsed by    APurify  (a
  100.     library call, maybe).
  101.  
  102.     In case of an error, APurify displays the blocks that surrounds the
  103.     illegal access and the  number  of    bytes  to  those  blocks.  It  also
  104.     displays a block for the accessed address. In that block, the beginning
  105.     address is the faultly address, the length is the size of the access (1
  106.     for a byte access, 2 for a short, 4 for a int/long    and  >4  for  movem
  107.     instruction). Attributes are R or W wether it's a read or write access.
  108.     The text-field contains the name of the procedure in which the  illegal
  109.     access had happened.
  110.  
  111.     APurify checks the memory allocated but not freed by  the  program.
  112.     (in fact, it detects non deallocated-blocks on library-closing time).
  113.  
  114.     It  knows  about  memory  location  independant  of   the   program
  115.     execution. That is to say, the first kilobyte of memory  that  contains
  116.     interrupt vectors of the 680x0 processor, the program segments and    the
  117.     stack. Accessing to those blocks will not be illegal. They    got  the  S
  118.     attribute (for SYSTEM blocks).
  119.  
  120.     It takes into  account    memory    block  allocated  by  malloc()  and
  121.     AllocMem(), and indirect allocated block (by OpenScreen() for example).
  122.     But I did not test the last kind of allocation. Anyway,  it  should  be
  123.     ok, because APurify patches AllocMem()  &  FreeMem()  entries.  Thus  a
  124.     program can access to the bitplanes of one of its screen without error.
  125.  
  126.     If  the  program  makes  a  legal  access,   but   attributes    are
  127.     incompatible  with    the  access-kind,  a  protection-error    message  is
  128.     displayed. Actually only the first kilobyte is write-protected (so that
  129.     one can read ExecBase). But it may change in the future.
  130.  
  131.     In order to speed up block  searching,    APurify  uses  a  cache  of
  132.     recently accessed blocks. Thus, even if there  is  a  large  amount  of
  133.     memory blocks, execution should not be slowed down too much.
  134.  
  135. USAGE:
  136. -----
  137.     One can see APurify as a pre-assembler. It must be used on assembly
  138.     language sourcefile just before the assembler takes place. It scan    the
  139.     file and change it a bit so that APur.lib can be used.
  140.  
  141.     Normal way to use it for a C program is to:
  142.  
  143.     - compile C sourcefiles and leave assembly language source (.asm).
  144.     - use APurify on each .asm file.
  145.     - link all .o files together with APur.lib.
  146.  
  147.     As you can see, APurify needs no change to your C  files  to  be  used.
  148.     However, the library must be opened by calling AP_Init() in the  main()
  149.     function and, *VERY IMPORTANT*, closed before exiting  the    program  by
  150.     calling AP_Close() (just before every exit() func-call,  for  example).
  151.     As a matter of fact, since some system  functions  are  patched,  if  a
  152.     program exits without closing the library, you'll meet  the  guru  (ie:
  153.     the computer will crash)... (You've been warned :-). The easiest way to
  154.     do this is to use atexit() (for example,  by  calling  atexit(AP_Close)
  155.     just after calling AP_Init()).
  156.  
  157.     If you forget to open the library, a warning message will tell    you
  158.     about that and the program will go on without APurify.
  159.  
  160.     You can disable/enable printing of messages by    making    a  call  to
  161.     AP_Report(flag). If flag is true then printing is  enabled,  if  it  is
  162.     false, no output will be done. This is usefull for    startup-codes.    For
  163.     example, if you are using the argv[] array in C, APurify  will  make  a
  164.     lot of false-error printing. This is because the values pointed by this
  165.     array is allocated before the library is opened. You can avoid this  by
  166.     calling AP_Report(0) before, and AP_Report(1) after, the code that uses
  167.     argv[].
  168.  
  169.     You can use APurify on any  language  that  generates  a  temporary
  170.     assembly language sourcefile (included assembly itself :-) ). You  must
  171.     notice too, that you can use it on programs for which no source-code is
  172.     available (or .o files without .asm files). For  that,  use  a  program
  173.     that  makes  reverse  engineering  on   your   executable    (ie:   that
  174.     disassembles the executable and  produces  a  .asm    file  ready  to  be
  175.     assembled). Then, with minor changes (prepend '_' to every  label,  put
  176.     calls AP_Init & AP_Close to right places), you get a file ready  to  be
  177.     processed by APurify.
  178.  
  179.     When processing a file, APurify puts some func-calls and some extra
  180.     data sections in the file. There are different  syntax  to    insert    new
  181.     sections and to  import  new  functions,  according  to  the  compiler.
  182.     APurify find which syntax should be used  by  analysing  the  file.  It
  183.     knowns the pseudo-instructions dseg/csed & public (AZTEC) and section &
  184.     xref/xef (DICE, HCC, ...). If a compiler uses  the  same  instructions,
  185.     you can use APurify with it (but it has just been tested with DICE !).
  186.  
  187.     The library APur.lib included is a DICE library.  It  can  be  used
  188.     with other compilers if they know that kind of file (standard COMMODORE
  189.     format). However, DICE uses a specific symbol for the stack base (ULONG
  190.     *_ExitSP). If your compiler doesn't known that variable,  you  have  to
  191.     build it. For that, declare it as a global variable. Make it points  to
  192.     the return-to-system address pushed in the bottom of the stack  by    the
  193.     system (ie: 8 bytes below stack base). And subtract 44  bytes.  To  sum
  194.     up, use the following formula:
  195.  
  196.        ULONG *_ExitSP = (ULONG *)((char *)Process_Stack_Base - 8 - 44).
  197.  
  198.     Indeed, the stack base of a program (Process_Stack_Base) is not  always
  199.     the one indicated by the system flags (I don't know  why...).  However,
  200.     you can compute it by  using  one  of  the    global    variables  of  your
  201.     compiler. For example, the _exit() procedure should use a variable that
  202.     points to the return-to-system address on stack. Then, the    stack  base
  203.     is that address + 8 bytes. Now, you should adapt the  formula  to  your
  204.     compiler.
  205.  
  206.     If anyway, the library is not good, you  can  rebuild  it:  compile
  207.     APfunc.c and APserv.a (modify them to your needs), and then  join  them
  208.     together to create APur.lib.
  209.  
  210. LEGAL PART:
  211. ----------
  212.     That program is provided 'AS IS'. I  am  not  responsible  for  any
  213.     dammage it can cause (but I am responsible for the benefits it can give
  214.     to you :-). Use that software at you own risks.
  215.  
  216.     That program is FREEWARE. You can use and distribute it as long  as
  217.     you keep the archive  intact  (no  adulteration  of  files  except  for
  218.     compression). It can't be sold without my agreement (except  a  minimal
  219.     amount for media support). You must ask me for commercial use  of  (any
  220.     part of) that product. I keep all my rights on  that  program  and    its
  221.     future releases. I can modify that software without telling it  to    the
  222.     users.
  223.  
  224.     If you wish, you can send me a postcard or anything else  you  want
  225.     (money, documentation, amiga, hardware  stuff,  ...)  in  exchange  for
  226.     using APurify. But there is no obligation :-). My postal address is:
  227.  
  228.         M. DEVULDER Samuel
  229.         1, Rue du chateau
  230.         59380 STEENE
  231.         FRANCE
  232.  
  233.     (yes I'm french !). You can  send  suggestions  or  bugs  to  my  email
  234.     address:
  235.  
  236.         devulder@info.unicaen.fr
  237.  
  238. DISTRIBUTION:
  239. ------------
  240.     That archive contains french and english version of APurify:
  241.  
  242.     - doc/APurify.doc:     The file you are currently reading.
  243.     - doc/APurify.doc.fre: French doc file.
  244.  
  245.      _/ - bin/APurify.fre:     French version of the parser.
  246.     | \ - bin/APurify:           English version of the parser.
  247.     |
  248.     +-----> to be renamed as APurify according to your choice.
  249.  
  250.      _/ - lib/APur.lib.fre:    French version of the library.
  251.     | \ - lib/APur.lib:        English version of the library.
  252.     |
  253.     +-----> to be renamed as APur.lib according to your choice. That
  254.         library is in COMMODORE format (generated by DICE).
  255.  
  256.      _/ - lib/APserv.a
  257.     | \ - lib/APfuncs.c
  258.     |
  259.     +-----> to re-build the library.
  260.  
  261.     - test/test.c:           Source of a stupid test file
  262.     - test/test.fre:       Test file linked with APur.lib.fre
  263.     - test/test:           Test file linked with APur.lib.
  264.  
  265. NOTES:
  266. -----
  267.     My configuration is: one old A500 (1989),  1Mo  RAM,  1  diskdrive,
  268.     KS1.3 and a lot of patience (ah, I wish I had an A4000/040/33Mhz !).
  269.  
  270.     I had the idea of that program    after  a  chat    with  Cedric  BEUST
  271.     (AMIGA NEWS) on IRC (Internet Relay Chat). Thanks Cedric !
  272.  
  273.     All marks are proprietary of their respective owners.
  274.  
  275.     APurify has been compiled with netdcc, the  non-registered  version
  276.     of DICE, by Matt DILLON.
  277.  
  278.     The parser is build from the TOP optimizer of HCC distribution ((c)
  279.     Sozobon ltd, Tony Andrews & Detlef Wuerkner).
  280.  
  281.     There are some programs like APurify. For example,  FORTIFY  (Simon
  282.     P. Bullen), but  it  only  detects    illegal  writes  to  boundaries  of
  283.     allocated blocks. Thus it can't detect big oversteps and  oversteps  in
  284.     reading and the detection is not real-time. Enforcer can detect illegal
  285.     access to memory (I think), but it needs a special device (MMU).
  286.  
  287. BUGS:
  288. ----
  289.     APurify don't known public memory where a program can read or write
  290.     without having allocated it. Thus, it  will  report  an  error  when  a
  291.     program reads or writes values in a message obtained  through  GetMsg()
  292.     calls.
  293.  
  294.     It  can  only  scan  68000  codes.  If    the   sourcefile   contains
  295.     instructions for 680x0 (x>1) processors, it will complain (at least for
  296.     new adressing modes). That will change if I found the source of a 680x0
  297.     (x>1) assembler (but I need time, and you're welcome to  tell  me  that
  298.     you got one).
  299.  
  300.     It can display messages about closing the library  without  freeing
  301.     some memory blocks. This is due to printf() that allocates memory  that
  302.     is free'd on exit. This is not a real bug, but you can  avoid  this  by
  303.     doing a AP_Report(0) just before exiting. But you must notice  that  it
  304.     is better to display false bugs than to not display real ones.
  305.  
  306.     Certainly more bugs, but I'm waiting for your bug-reports.
  307.  
  308.